#include <51func.h>
typedef struct train_s {
    int length;
    char data[1000];
} train_t;
//1 
//int recvfile(int sockfd){
//    char filename[1024] = {0};
//    recv(sockfd,filename,sizeof(filename),0);
//    int fd = open(filename,O_RDWR|O_CREAT,0600);
//    char buf[1024] = {0};
//    ssize_t sret = recv(sockfd,buf,sizeof(buf),0);
//    write(fd,buf,sret);
//    return 0;
//}
//2
//int recvfile(int sockfd){
//    train_t train;
//    recv(sockfd,&train.length,sizeof(train.length),0);
//    recv(sockfd,&train.data,train.length,0);
//    char filename[1024] = {0};
//    memcpy(filename,train.data,train.length);
//    int fd = open(filename,O_RDWR|O_CREAT,0600);
//    recv(sockfd,&train.length,sizeof(train.length),0);
//    recv(sockfd,&train.data,train.length,0);
//    write(fd,train.data,train.length);
//    return 0;
//}
//3
int recvn(int sockfd, void *buf, int length){
    int total = 0; //已经接收的长度
    char *p = (char *)buf; // char的单位为1
    while(total < length){
        ssize_t sret = recv(sockfd,p+total,length-total,0);
        total += sret;
    }
    return 0;
}
//3
//int recvfile(int sockfd){
//    train_t train;
//    //recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);
//    //recv(sockfd,&train.data,train.length,MSG_WAITALL);
//    recvn(sockfd,&train.length,sizeof(train.length));
//    recvn(sockfd,train.data,train.length);
//    char filename[1024] = {0};
//    memcpy(filename,train.data,train.length);
//    int fd = open(filename,O_RDWR|O_CREAT,0600);
//    off_t filesize;
//    recvn(sockfd,&train.length,sizeof(train.length));
//    recvn(sockfd,train.data,train.length);
//    memcpy(&filesize,train.data,train.length);
//    printf("filesize = %ld\n", filesize);
//    off_t cursize = 0;
//    off_t slice = filesize/10000;
//    off_t lastsize = 0; //上一次打印进度的时候文件大小
//    while(1){
//        //recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);
//        recvn(sockfd,&train.length,sizeof(train.length));
//        if(train.length == 0){
//            break;
//        }
//        if(train.length != 1000){
//            printf("train.length = %d\n", train.length);
//        }
//        //recv(sockfd,&train.data,train.length,MSG_WAITALL);
//        recvn(sockfd,train.data,train.length);
//        write(fd,train.data,train.length);
//        cursize += train.length;
//        if(cursize - lastsize > slice){
//            printf("%5.2lf%%\r", 100.0*cursize/filesize);
//            fflush(stdout);
//            lastsize = cursize;
//        }
//    }
//    printf("100.00%%\n");
//    return 0;
//}
// 4
int recvfile(int sockfd){
    train_t train;
    //recv(sockfd,&train.length,sizeof(train.length),MSG_WAITALL);
    //recv(sockfd,&train.data,train.length,MSG_WAITALL);
    recvn(sockfd,&train.length,sizeof(train.length));
    recvn(sockfd,train.data,train.length);
    char filename[1024] = {0};
    memcpy(filename,train.data,train.length);
    int fd = open(filename,O_RDWR|O_CREAT,0600);
    off_t filesize;
    recvn(sockfd,&train.length,sizeof(train.length));
    recvn(sockfd,train.data,train.length);
    memcpy(&filesize,train.data,train.length);
    printf("filesize = %ld\n", filesize);
    ftruncate(fd,filesize);
    char *p = (char *)mmap(NULL,filesize,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    recvn(sockfd,p,filesize);
    munmap(p,filesize);
    printf("100.00%%\n");
    return 0;
}
int main(int argc, char *argv[])
{
    // ./client 192.168.118.128 1234
    ARGS_CHECK(argc,3);
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in addr;//赋值使用的 struct sockaddr_in
    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(argv[2]));
    addr.sin_addr.s_addr = inet_addr(argv[1]);
    // 传参 先取地址 再强转
    int ret = connect(sockfd,(struct sockaddr *)&addr,sizeof(addr));
    ERROR_CHECK(ret,-1,"connect");
    recvfile(sockfd);
    return 0;
}

